package ch.sfug.anim.tween {
	import flash.display.FrameLabel;
	import flash.display.MovieClip;
	
	import ch.sfug.anim.tween.AbstractTween;	

	/**
	 * @author loop
	 */
	public class TimelineTween extends AbstractTween {

		private var sf:Number;
		private var ef:Number;
		private var cf:Number;
		private var ease:Function;

		public function TimelineTween( t:MovieClip = null, d:int = int.MAX_VALUE ) {
			super(t, d);
			ease = linear;
		}

		
		public function playToLabel( label:String, easing:Function = null ):void {
			sf = cf = mc.currentFrame;
			ef = getFrameofLabel(label);
			if( easing != null ) ease = easing;
			start();
		}

		
		public function playFromToLabel( from_label:String, to_label:String, easing:Function = null ):void {
			sf = cf = getFrameofLabel(from_label);
			ef = getFrameofLabel(to_label);
			if( easing != null ) ease = easing;
			start();
		}

		
		public function gotoAndStop( frame:int ):void {
			mc.gotoAndStop(Math.max(Math.min(mc.totalFrames, frame), 1));
		}

		
		/**
		 * returns the frame number of the label
		 */
		private function getFrameofLabel( label:String ):int {
			for each (var i:FrameLabel in mc.currentLabels ) {
				if( i.name == label ) return i.frame;
			}
			throw new Error("could not find label: " + label + " on movieclip: " + target);
		}

		
		/**
		 * overwrite superfunction to interpolate on the properties
		 */
		protected override function interpolate( c:Number, d:Number ):void {
			if( cf == ef ) {
				mc.gotoAndStop(cf);
				super.stop();
			} else {
				if( d == int.MAX_VALUE ) {
					// frame based
					mc.gotoAndStop(cf);
					cf += ( sf > ef ) ? -1 : 1;
				} else {
					// duration based
					mc.gotoAndStop(cf);
					cf = Math.round(ease(c, sf, ef - sf, d));
				}
			}
			super.interpolate( c, d );
		}

		
		/**
		 * sets/gets the duration of the tween
		 */
		public override function set duration( d:uint ):void {
			if( d >= 0 ) {
				this.d = d;
			} else {
				throw new Error("you have to specify a duration bigger equals than 0 and not: " + d + " for the tween: " + this);
			}
		}

		
		private function get mc():MovieClip {
			return MovieClip(t);
		}
	}
}
